home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Talking Clock Pro™ 2.0.1 / Talking Clock Pro Source / Controller / Source / clockrec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-24  |  11.1 KB  |  469 lines  |  [TEXT/CWIE]

  1. /*
  2.  * clockrec.c
  3.  */
  4.  
  5. #include <AERegistry.h>
  6. #include <AEObjects.h>
  7.  
  8. #include <Icons.h>    //    #include <PlotIconSuite.h>
  9. #include "TalkConstants.h"
  10.  
  11. #include "apprec.h"
  12. #include "clockrec.h"
  13. #include "x.h"
  14. #include "menu.h"
  15. #include "window.h"
  16. #include "util.h"
  17. #include "str.h"
  18.  
  19.  
  20. #define DAEMON_TYPE    'appe'
  21. #define DAEMON_ALT    'APPL'
  22. #define DAEMON_SIG    'O\'CL'
  23.  
  24. Boolean hasController ;
  25.  
  26. DefWindowRec clockRec = {
  27.  
  28.     128 , NULL ,
  29.  
  30.     ClockCr ,
  31.     ClockDe ,
  32.     ClockUp ,
  33.     ClockMD ,
  34.     ClockMU ,
  35.     ClockKD ,
  36.     ClockAK ,
  37.     ClockAc ,
  38.     ClockSw ,
  39.     ClockId ,
  40.     ClockPr ,
  41.     ClockCo ,
  42.     ClockAE
  43.  
  44. } ;
  45.  
  46.  
  47. typedef struct ClockRec {
  48.     ProcessSerialNumber    psn ; /* The extension's process */
  49.     short                turnaround ;
  50.     Boolean                optionKeyTalk ;
  51.     Boolean                controlKeyTalk ;
  52.     Boolean                commandKeyTalk ;
  53.     Boolean                shiftKeyTalk ;
  54.     Boolean                capsLockKeyTalk ;
  55.     Boolean                fiveMinuteTalk ;
  56. } ClockRec , * ClockPtr ;
  57.  
  58.  
  59. typedef struct Switch {
  60.     short                xPos ;
  61.     short                yPos ;
  62.     short                xSize ;
  63.     short                ySize ;
  64.     short                nameIndex ;
  65.     OSType                prop ;
  66. } Switch , * SwitchPtr ;
  67.  
  68.  
  69. SwitchPtr switches = NULL ;
  70. int NUM_SWITCHES = 0 ;
  71.  
  72.  
  73.  
  74. static void
  75. ReadSwitches ( void ) {
  76.  
  77. Handle h ;
  78. int ix ;
  79.  
  80.     NUM_SWITCHES = Count1Resources ( 'SWTC' ) ;
  81.     switches = ( SwitchPtr ) NewPtrClear ( sizeof ( Switch ) * NUM_SWITCHES ) ;
  82.     for ( ix = 0 ; ix < NUM_SWITCHES ; ix ++ ) {
  83.         h = Get1IndResource ( 'SWTC' , ix + 1 ) ;
  84.         HLock ( h ) ;
  85.         BlockMove ( * h , switches + ix , sizeof ( Switch ) ) ;
  86.         ReleaseResource ( h ) ;
  87.     }
  88. }
  89.  
  90.  
  91. static void
  92. DrawSwitch ( SwitchPtr sw , Boolean b ) {
  93.  
  94. Rect r ;
  95. Str63 name ;
  96.  
  97.     PenNormal ( ) ;
  98.     TextFont ( GetAppFont ( ) ) ;
  99.     TextSize ( sw -> ySize ) ;
  100.     SetRect ( & r , sw -> xPos , sw -> yPos , sw -> xPos + sw -> ySize ,
  101.         sw -> yPos + sw -> ySize ) ;
  102.     FrameRect ( & r ) ;
  103.     if ( b ) {
  104.         MoveTo ( r . left , r . top ) ;
  105.         Line ( sw -> ySize - 1 , sw -> ySize - 1 ) ;
  106.         MoveTo ( r . left , r . bottom - 1 ) ;
  107.         Line ( sw -> ySize - 1 , 1 - sw -> ySize ) ;
  108.     }
  109.     MoveTo ( sw -> xPos + 2 * sw -> ySize , sw -> yPos + sw -> ySize * 4 / 5 + 1 ) ;
  110.     GetIndString ( name , 132 , sw -> nameIndex ) ;
  111.     DrawString ( name ) ;
  112. }
  113.  
  114.  
  115. static Boolean
  116. TrackSwitch ( SwitchPtr sp ) {
  117.  
  118. Rect r , box ;
  119. Boolean in = 0 ;
  120. Boolean toIn = 1 ;
  121. Point p ;
  122.  
  123.     SetRect ( & r , sp -> xPos , sp -> yPos , sp -> xPos + sp -> xSize ,
  124.         sp -> yPos + sp -> ySize ) ;
  125.     box = r ;
  126.     box . right = box . left + sp -> ySize ;
  127.     InsetRect ( & box , 1 , 1 ) ;
  128.     PenMode ( patXor ) ;
  129.     while ( StillDown ( ) ) {
  130.         GetMouse ( & p ) ;
  131.         toIn = PtInRect ( p , & r ) ;
  132.         if ( toIn != in ) {
  133.             FrameRect ( & box ) ;
  134.             in = toIn ;
  135.         }
  136.     }
  137.     if ( in ) {
  138.         FrameRect ( & box ) ;
  139.     }
  140.     PenNormal ( ) ;
  141.  
  142.     return in ;
  143. }
  144.  
  145.  
  146. Boolean
  147. FindPSN ( OSType type , OSType creator , ProcessSerialNumber * psn ) {
  148.  
  149. ProcessInfoRec prInfo ;
  150.  
  151.     psn -> highLongOfPSN = 0 ;
  152.     psn -> lowLongOfPSN = kNoProcess ;
  153.     while ( ! GetNextProcess ( psn ) ) {
  154.         prInfo . processInfoLength = sizeof ( ProcessInfoRec ) ;
  155.         prInfo . processName = NULL ;
  156.         prInfo . processAppSpec = NULL ;
  157.         FailErr ( GetProcessInformation ( psn , & prInfo ) ) ;
  158.         if ( prInfo . processType == type &&
  159.             prInfo . processSignature == creator ) {
  160.             return 1 ;
  161.         }
  162.     }
  163.     return 0 ;
  164. }
  165.  
  166.  
  167. static Boolean
  168. GetRecData ( ClockPtr ptr , DescType theKey ) {
  169.  
  170. AEDesc aed ;
  171. AERecord rec ;
  172. AppleEvent aevt ;
  173. AppleEvent reply = { 0 , 0 } ;
  174. DescType type ;
  175. Boolean b ;
  176. long theSize ;
  177.  
  178.     FailErr ( AECreateDesc ( typeProcessSerialNumber , ( Ptr ) & ( ptr -> psn ) ,
  179.         sizeof ( ProcessSerialNumber ) , & aed ) ) ;
  180.     FailErr ( AECreateAppleEvent ( kAECoreSuite , kAEGetData , & aed ,
  181.         kAutoGenerateReturnID , kAnyTransactionID , & aevt ) ) ;
  182.     FailErr ( AEDisposeDesc ( & aed ) ) ;
  183.     FailErr ( AECreateList ( NULL , 0L , 1 , & rec ) ) ;
  184.     type = cProperty ;
  185.     FailErr ( AEPutKeyPtr ( & rec , keyAEDesiredClass , typeType ,
  186.         ( Ptr ) & type , sizeof ( type ) ) ) ;
  187.     type = theKey ;
  188.     FailErr ( AEPutKeyPtr ( & rec , keyAEKeyData , typeType ,
  189.         ( Ptr ) & type , sizeof ( type ) ) ) ;
  190.     FailErr ( AEPutParamDesc ( & aevt , keyDirectObject , & rec ) ) ;
  191.     FailErr ( AEDisposeDesc ( & rec ) ) ;
  192.     type = typeBoolean ;
  193.     FailErr ( AEPutParamPtr ( & aevt , keyAERequestedType , typeType ,
  194.         ( Ptr ) & type , sizeof ( type ) ) ) ;
  195.     FailErr ( AESend ( & aevt , & reply , kAEWaitReply , kAEHighPriority ,
  196.         20L , NULL , NULL ) ) ;
  197.     FailErr ( AEDisposeDesc ( & aevt ) ) ;
  198.     FailErr ( AEGetParamPtr ( & reply , keyAEResult , typeBoolean , & type ,
  199.         ( Ptr ) & b , sizeof ( b ) , & theSize ) ) ;
  200.     FailErr ( AEDisposeDesc ( & reply ) ) ;
  201.  
  202.     return b ;
  203. }
  204.  
  205.  
  206. static void
  207. SetRecData ( ClockPtr ptr , DescType theKey , Boolean b ) {
  208.  
  209. AEDesc aed = { 0 , 0 } ;
  210. AERecord rec = { 0 , 0 } ;
  211. AppleEvent aevt = { 0 , 0 } ;
  212. AppleEvent reply = { 0 , 0 } ;
  213. DescType type ;
  214.  
  215.     TRY {
  216.         FailErr ( AECreateDesc ( typeProcessSerialNumber , ( Ptr ) & ( ptr -> psn ) ,
  217.             sizeof ( ProcessSerialNumber ) , & aed ) ) ;
  218.         FailErr ( AECreateAppleEvent ( kAECoreSuite , kAESetData , & aed ,
  219.             kAutoGenerateReturnID , kAnyTransactionID , & aevt ) ) ;
  220.         FailErr ( AECreateList ( NULL , 0L , 1 , & rec ) ) ;
  221.         type = cProperty ;
  222.         FailErr ( AEPutKeyPtr ( & rec , keyAEDesiredClass , typeType ,
  223.             ( Ptr ) & type , sizeof ( type ) ) ) ;
  224.         type = theKey ;
  225.         FailErr ( AEPutKeyPtr ( & rec , keyAEKeyData , typeType ,
  226.             ( Ptr ) & type , sizeof ( type ) ) ) ;
  227.         FailErr ( AEPutParamDesc ( & aevt , keyDirectObject , & rec ) ) ;
  228.         FailErr ( AEPutParamPtr ( & aevt , keyAEData , typeBoolean ,
  229.             ( Ptr ) & b , sizeof ( b ) ) ) ;
  230.         FailErr ( AESend ( & aevt , & reply , kAENoReply , kAEHighPriority ,
  231.             20L , NULL , NULL ) ) ;
  232.     } CLEANUP {
  233.         FailErr ( AEDisposeDesc ( & rec ) ) ;
  234.         FailErr ( AEDisposeDesc ( & aed ) ) ;
  235.         FailErr ( AEDisposeDesc ( & aevt ) ) ;
  236.         FailErr ( AEDisposeDesc ( & reply ) ) ;
  237.         if ( __err == errAETimeout ) {
  238.             NO_PROPAGATE ;
  239.         }
  240.     } DONE ;
  241. }
  242.  
  243.  
  244. static void
  245. FillRec ( ClockPtr ptr ) {
  246.  
  247.     ptr -> optionKeyTalk = GetRecData ( ptr , pOptionKeyTalk ) ;
  248.     ptr -> commandKeyTalk = GetRecData ( ptr , pCommandKeyTalk ) ;
  249.     ptr -> controlKeyTalk = GetRecData ( ptr , pControlKeyTalk ) ;
  250.     ptr -> shiftKeyTalk = GetRecData ( ptr , pShiftKeyTalk ) ;
  251.     ptr -> capsLockKeyTalk = GetRecData ( ptr , pCapsLockKeyTalk ) ;
  252.     ptr -> fiveMinuteTalk = GetRecData ( ptr , pFiveMinuteTalk ) ;
  253. }
  254.  
  255.  
  256. static void
  257. SetRec ( ClockPtr ptr ) {
  258.  
  259.     SetRecData ( ptr , pOptionKeyTalk , ptr -> optionKeyTalk ) ;
  260.     SetRecData ( ptr , pCommandKeyTalk , ptr -> commandKeyTalk ) ;
  261.     SetRecData ( ptr , pControlKeyTalk , ptr -> controlKeyTalk ) ;
  262.     SetRecData ( ptr , pShiftKeyTalk , ptr -> shiftKeyTalk ) ;
  263.     SetRecData ( ptr , pCapsLockKeyTalk , ptr -> capsLockKeyTalk ) ;
  264.     SetRecData ( ptr , pFiveMinuteTalk , ptr -> fiveMinuteTalk ) ;
  265. }
  266.  
  267.  
  268. /*    A window is being created or opened. Allocate data and        */
  269. /*    select the window                                    */
  270. OSErr
  271. ClockCr ( WindowPtr wp , Handle * data , FSSpec * file ) {
  272.  
  273. ClockPtr ptr ;
  274.  
  275.     if ( ! NUM_SWITCHES ) {
  276.         ReadSwitches ( ) ;
  277.     }
  278.     * data = NewHandle ( sizeof ( ClockRec ) ) ;
  279.     FailNil ( * data ) ;
  280.     HLockHi ( * data ) ;
  281.     ptr = ( ClockPtr ) * * data ;
  282.     if ( ! FindPSN ( DAEMON_TYPE , DAEMON_SIG , & ( ptr -> psn ) ) &&
  283.             !FindPSN(DAEMON_ALT, DAEMON_SIG, &ptr->psn)) {
  284.         Alert ( 130 , NULL ) ;
  285.         hasController = 0 ;
  286.         return 1 ;
  287.     } else {
  288.         FillRec ( ptr ) ;
  289.         hasController = 1 ;
  290.     }
  291.     return noErr ;
  292. }
  293.  
  294.  
  295. /*    Window is being destroyed. Put up a warning dialog, and        */
  296. /*    return errCancel if the user cancels closing - else call    */
  297. /*    DisposeWindow here                                            */
  298. OSErr
  299. ClockDe ( WindowPtr wp , Handle data ) {
  300.  
  301. ProcessSerialNumber psn ;
  302.  
  303.     if ( hasController ) {
  304.         SetRec ( ( ClockPtr ) * data ) ;
  305.         hasController = 0 ;
  306.         if ( FindPSN ( 'FNDR' , 'MACS' , & psn ) ) {
  307.             FailErr ( SetFrontProcess ( & psn ) ) ;
  308.         }
  309.     }
  310.     DisposeHandle ( data ) ;
  311.     DisposeWindow ( wp ) ;
  312.     return noErr ;
  313. }
  314.  
  315.  
  316. /*    Update the window - BeginUpdate is already called            */
  317. OSErr
  318. ClockUp ( WindowPtr wp , Handle data , EventRecord * event ) {
  319.  
  320. short ix ;
  321. Handle h ;
  322. ClockPtr ptr = ( ClockPtr ) * data ;
  323. Rect r = { 10 , 10 , 42 , 42 } ;
  324. Str255 s ;
  325.  
  326.     FailErr ( GetIconSuite ( & h , 128 , -1L ) ) ;
  327.     EraseRect ( & ( wp -> portRect ) ) ;
  328.     FailErr ( PlotIconSuite ( & r , atNone , ttNone , h ) ) ;
  329.     FailErr ( DisposeIconSuite ( h , FALSE ) ) ;
  330.  
  331.     TextFont ( GetAppFont ( ) ) ;
  332.     TextSize ( GetDefFontSize ( ) ) ;
  333.  
  334.     SetRect ( & r , 52 , 10 , wp -> portRect . right - 8 , 40 ) ;
  335.     GetIndString ( s , 131 , 1 ) ;
  336.     TextBox ( & s [ 1 ] , s [ 0 ] , & r , teFlushDefault ) ;
  337.  
  338.     TextSize ( GetDefFontSize ( ) * 4 / 5 ) ;
  339.  
  340.     SetRect ( & r , 10 , 52 , wp -> portRect . right - 8 , 80 ) ;
  341.     GetIndString ( s , 131 , 2 ) ;
  342.     TextBox ( & s [ 1 ] , s [ 0 ] , & r , teFlushDefault ) ;
  343.  
  344.     SetRect ( & r , 10 , wp -> portRect . bottom - 35 ,
  345.         wp -> portRect . right - 8 , wp -> portRect . bottom ) ;
  346.     GetIndString ( s , 131 , 3 ) ;
  347.     TextBox ( & s [ 1 ] , s [ 0 ] , & r , teFlushDefault ) ;
  348.  
  349.     for ( ix = 0 ; ix < NUM_SWITCHES ; ix ++ ) {
  350.         DrawSwitch ( & switches [ ix ] , !! ( & ( ptr -> optionKeyTalk ) ) [ ix ] ) ;
  351.     }
  352.     return noErr ;
  353. }
  354.  
  355.  
  356. /*    The user clicked in your window. The window port is set and    */
  357. /*    event -> where is translated into local coordinates now        */
  358. OSErr
  359. ClockMD ( WindowPtr wp , Handle data , EventRecord * event ) {
  360.  
  361. short ix ;
  362. Rect r ;
  363. SwitchPtr sp = switches ;
  364. ClockPtr ptr = ( ClockPtr ) * data ;
  365.  
  366.     for ( ix = 0 ; ix < NUM_SWITCHES ; ix ++ ) {
  367.         SetRect ( & r , sp -> xPos , sp -> yPos , sp -> xPos + sp -> xSize ,
  368.             sp -> yPos + sp -> ySize ) ;
  369.         if ( PtInRect ( event -> where , & r ) ) {
  370.             break ;
  371.         }
  372.         sp ++ ;
  373.     }
  374.     if ( ix < NUM_SWITCHES ) {
  375.         if ( TrackSwitch ( sp ) ) {
  376.             ( & ( ptr -> optionKeyTalk ) ) [ ix ] = ! ( & ( ptr -> optionKeyTalk ) ) [ ix ] ;
  377.             SetPort ( wp ) ;
  378.             InvalRect ( & r ) ;
  379.         }
  380.     }
  381.     return noErr ;
  382. }
  383.  
  384.  
  385. /*    MouseUp in a window - you probably should do nothing        */
  386. OSErr
  387. ClockMU ( WindowPtr wp , Handle data , EventRecord * event ) {
  388.  
  389.     return noErr ;
  390. }
  391.  
  392.  
  393. /*    The user typed in the window - command keys are already        */
  394. /*    taken care of and don't come here                            */
  395. OSErr
  396. ClockKD ( WindowPtr wp , Handle data , EventRecord * event ) {
  397.  
  398.     return noErr ;
  399. }
  400.  
  401.  
  402. /*    You probably just want to call the KeyDown handler here        */
  403. OSErr
  404. ClockAK ( WindowPtr wp , Handle data , EventRecord * event ) {
  405.  
  406.     return noErr ;
  407. }
  408.  
  409.  
  410. /*    Activate event - highlight/dehighlight controls & caret        */
  411. OSErr
  412. ClockAc ( WindowPtr wp , Handle data , EventRecord * event ) {
  413.  
  414.     return noErr ;
  415. }
  416.  
  417.  
  418. /*    You should probably build a suitable activate event and        */
  419. /*    send to the activate handling for MultiFinder switches        */
  420. OSErr
  421. ClockSw ( WindowPtr wp , Handle data , EventRecord * event ) {
  422.  
  423.     return noErr ;
  424. }
  425.  
  426.  
  427. /*    Idle time - set the sleep parameter if it's too large for    */
  428. /*    your needs. GetCaretTime() is a good value for text editors    */
  429. OSErr
  430. ClockId ( WindowPtr wp , Handle data , long * sleep ) {
  431.  
  432.     return AppId ( wp , app . data , sleep ) ;
  433. }
  434.  
  435.  
  436. /*    This is called when menus need to be updated.                */
  437. OSErr
  438. ClockPr ( WindowPtr wp , Handle data ) {
  439.  
  440.     FailErr ( AppPr ( wp , app . data ) ) ;
  441.     EnableCmd ( FILE_MENU , CLOSE_ITEM ) ;
  442.     return noErr ;
  443. }
  444.  
  445.  
  446. /*    A menu selection was made - take appropriate action            */
  447. OSErr
  448. ClockCo ( WindowPtr wp , Handle data , short menu , short item ,
  449.     unsigned char * itemStr ) {
  450.  
  451.     if ( menu == FILE_MENU && item == CLOSE_ITEM ) {
  452.         DestroyWindow ( wp ) ;
  453.     } else {
  454.         FailErr ( AppCo ( wp , app . data , menu , item , itemStr ) ) ;
  455.     }
  456.  
  457.     return noErr ;
  458. }
  459.  
  460.  
  461. /*    An AppleEvent was received with this window in front        */
  462. OSErr
  463. ClockAE ( WindowPtr wp , Handle data , AppleEvent * event ,
  464.     AppleEvent * reply ) {
  465.  
  466.     return noErr ;
  467. }
  468.  
  469.